const express = require('express')
const path = require('path')
const bodyParser = require('body-parser')
const jwt = require('jsonwebtoken')
const app = express()
const statiPath = path.join(__dirname, './public')
app.use(express.static(statiPath))
app.use(bodyParser.urlencoded({ extend: false }))

// 鉴权
app.use((req, res, next) => {
  // 如果不是登录页面，则需要鉴权
  if (req.url != '/login') {
    const token = req.headers.authorization;
    try {
      const obj = jwt.verify(token, 'login jwt')
      req.query.nickname = obj.username;
    } catch (ex) {
      return res.send({ isOk: false, message: '无权限' })
    }
  }
  // 鉴权通过，则可以继续请求
  next()


})

// 存放所有登录的用户的socket
let users = [];

// 登录接口
app.post('/login', (req, res) => {
  const nickname = req.body.nickname;
  // 判断昵称是否为空
  if (nickname.trim().length == 0) {
    return res.send({ login: false, message: '昵称不能为空' })
  }
  // 检测该昵称是否已经存在
  const isExist = users.find((socket) => { return socket.nickname == nickname })
  if (isExist) {
    return res.send({ login: false, message: '该昵称已经被占用，请更换昵称！' })
  }
  // 可以使用，jwt签名,鉴权使用
  // sign(要签名的数据,私钥,其他配置),返回签名
  const token = jwt.sign({ username: nickname }, 'login jwt', {
    expiresIn: 60 * 60 * 24 * 3   // 过期时间
  })

  return res.send({ login: true, message: '可以使用', token: token })
})

// 鉴权通过
app.get('/authentication', (req, res) => {
  const nickname= req.query.nickname
  res.send({ isOk: true, nickname })
})

// 获取在线用户列表
app.get('/userlist', (req, res) => {
  var usernames = [];
  users.forEach(socket => {
    usernames.push({nickname:socket.nickname,id:socket.id});
  })
  res.send(usernames)
})

// 【重点-通过http模块Server方法获取关联Express的服务对象】
const server = require('http').Server(app);
// 【重点-导入socket.io模块获取io对象并关联http服务对象】
const io = require('socket.io')(server);

// 【重点-检测客户端和服务端是否连接成功】
io.on('connection', socket => {
  console.log('有一个客户端连接成功')
  socket.join('openTalk');   // 所有人加入同一组-openTalk
  // 监听当前客户端所传入的用户的名字
  socket.on('create', data => {
    socket.nickname = data;
    users.push(socket)
    io.emit('create',{message:`【室友-${socket.nickname}】上线啦`,online:true,id:socket.id,nickname:socket.nickname})
  })
  // 监听当前客户端向服务端发送的数据
  socket.on('message', data => {
    data.sendId = socket.id;
    data.sendName = socket.nickname;
    // 检测用户发送对象是私聊还是群聊
    if (data.id == 'all') {
      data.sendId = 'all';
      socket.broadcast.to('openTalk').emit('message',data)
    } else {
      const user = users.find(socket => { return socket.nickname == data.toUser });
      if (user) {
        user.emit('message',data)
      }
    }
    
  })
  // 检测一个客户端断开连接
  socket.on('disconnect', () => {
    console.log('一个客户端离开')
    // 找到用户列表中的当前端开连接的客户端的socket
    const index = users.findIndex(val => val.nickname == socket.nickname);
    // 从用户列表中移除
    users.splice(index, 1);
    // 广播-用户下线
    io.emit('create',{message:`【室友-${socket.nickname}】下线啦`,online:false,id:socket.id,nickname:socket.nickname})
  })
})

// 【重点-使用server监听80端口】
server.listen(80)
